﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data.Linq;
using System.Linq;
using System.Linq.Dynamic;
using System.Text.RegularExpressions;
using System.Web;
using DD = System.Web.DynamicData;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using Telerik.Web.UI;
using Dimok.Shared.Web;
using Data.LINQ;
using TelerikExtensions;

namespace Dimok.Web.UI {
	/// <summary>
	/// Summary description for ExtenderControl1
	/// </summary>
	[TargetControlType(typeof(Control))]
	public class RadGridExtender : ExtenderControl {
		#region Client Properties
		public string ProfileID { get; set; }
		public string DocksID { get; set; }
		public Type _wSEntityType = null;
		public Type WSEntityType { 
			get { if (_wSEntityType == null)throw new Exception("Entity Type is not provided in "+NamingContainer.GetType().Name); return _wSEntityType; }
			set { _wSEntityType = value; } }
		public string WSMethodName { get; set; }
		public string WSMethodName_Delete { get; set; }
		public string RowContextMenuID { get; set; }
		private string _defaultFilterTemp;
		public string DefaultFilterTemp {
			get { return (_defaultFilterTemp + "").Default(MotoBank.MetaModel.GetDefaultFilter(WSEntityType)); }
			set { _defaultFilterTemp = value; }
		}
		private string _defaultFields;
		public string DefaultFields {
			get { return _defaultFields; }
			set { _defaultFields = value; }
		}
		private string _defaultSort;
		public string DefaultSort {
			get { return (_defaultSort + "").Default(string.Join(",", MotoBank.MetaModel.GetSortFields(WSEntityType).ToArray())); }
			set { _defaultSort = value; }
		}
		private string _defaultOtherFields;
		public string DefaultOtherFields {
			get {	return (_defaultOtherFields + "").Default(string.Join(",", MotoBank.MetaModel.GetOrderedFields<DetailFieldAttribute>(WSEntityType).ToArray())	);}
			set { _defaultOtherFields = value; }
		}
		public string OnRowContextMenuShowing { get; set; }
		public string OnRowContextMenuShowed { get; set; }
		public string UniqueNameEditTypes { get; set; }
		public string Skin { get; set; }
		#endregion

		#region Properties
		RadGrid grid = null;
		RadNumericTextBox changePageSize = null;
		Profiler p;
		RadContextMenu rcmColumns;
		HtmlGenericControl rcmOtherFields;
		RadContextMenu rcmFilters;
		RadContextMenu rcmSortBys;
		RadContextMenu rcmRow;
		RadNumericTextBox goToPage;
		Control columnsMenu;
		Control otherFieldsMenu;
		Control filtersMenu;
		Control sortBysMenu;
		Control rowContextMenu;
		public string CssClass { get { return grid.CssClass; } set { grid.CssClass = value; } }
		public string Style { get { return grid.Style.Value; } set { grid.Style.Value = value; } }
		public event EventHandler<LinqDataSourceSelectEventArgs> DataSourceSelected;
		public string ReportNameCurrent { get; set; }
		private bool CanUpdate { get { return MotoBank.MetaModel.CanUpdate(WSEntityType); } }
		private bool CanDelete { get { return MotoBank.MetaModel.CanDelete(WSEntityType); } }
		private bool CanInsert { get { return MotoBank.MetaModel.CanInsert(WSEntityType); } }
		private struct MetaColumn {
			public string Name;
			public string DisplayName;
			public string DataFormatString;
			public Type ColumnType;
			public MetaColumn(string name,string  display, string format, Type type) {
				Name = name;
				ColumnType = type;
				DisplayName = display;
				DataFormatString = format;
			}
		}
		private MetaColumn[] _metaColumns;
		private MetaColumn[] MetaColumns {
			get {
				if (_metaColumns == null) {
					var columns = MotoBank.MetaModel.GetTable(WSEntityType).Columns
						.Select(c => new MetaColumn(c.Name,c.DisplayName,c.DataFormatString, c.ColumnType)).ToList();
					if (CanDelete) columns.Add(new MetaColumn("Delete", "<img src='/App_Themes/Office2007/Grid/Delete.gif'>", "", null));
					_metaColumns = columns.ToArray();
				}
				return _metaColumns;
			}
		}
		#endregion

		protected override void OnLoad(EventArgs e) {
			this.TraceMe("Start");
			int i = 0;
			base.OnLoad(e);
			grid = NamingContainer.Child<RadGrid>();
			if (grid == null) throw new NotSupportedException("Target controls [" + TargetControlID + "] other then Telerik.Web.UI are not supported.");

			#region Grid default properties
			grid.AllowCustomPaging = true;
			grid.AllowFilteringByColumn = true;
			grid.AllowMultiRowSelection = true;
			grid.AllowPaging = true;
			grid.AllowSorting = true;
			grid.AutoGenerateColumns = false;
			grid.ClientSettings.AllowColumnsReorder = true;
			grid.ClientSettings.ReorderColumnsOnClient = true;
			grid.ClientSettings.EnableRowHoverStyle = false;
			grid.ClientSettings.ColumnsReorderMethod = GridClientSettings.GridColumnsReorderMethod.Reorder;
			grid.ClientSettings.AllowKeyboardNavigation = true;
			grid.ClientSettings.Resizing.AllowColumnResize = true;
			grid.ClientSettings.Resizing.EnableRealTimeResize = true;
			grid.ClientSettings.Resizing.ResizeGridOnColumnResize = true;
			grid.ClientSettings.Selecting.AllowRowSelect = true;
			grid.CssClass += " CaptionLeft";
			grid.EnableViewState = false;
			grid.FilterItemStyle.Width = new Unit(95, UnitType.Percentage);
			grid.FilterItemStyle.Wrap = false;
			grid.MasterTableView.AllowCustomSorting = true;
			grid.MasterTableView.AllowMultiColumnSorting = true;
			grid.MasterTableView.AllowNaturalSort = true;
			grid.MasterTableView.Caption = NamingContainer.ID;
			grid.MasterTableView.Style.Add(HtmlTextWriterStyle.Width, "");
			grid.PagerStyle.AlwaysVisible = true;
			grid.PagerStyle.Mode = GridPagerMode.NextPrevNumericAndAdvanced;
			grid.PagerStyle.PagerTextFormat = "{4}<b>{5}</b> Rows. Page <b>{0}</b> of <b>{1}</b>.";
			grid.PagerStyle.VerticalAlign = VerticalAlign.Middle;
			grid.Skin = grid.FilterMenu.Skin = Skin == null ? "Office2007" : Skin;
			//grid.Style.Add("float", "left");
			#endregion

			this.TraceMe("Step:" + (++i));
			p = new Profiler(Page, this);
			var pageSize = p.Grid.PageSize;
			this.TraceMe("Step:" + (++i));
		
			if (pageSize > 0) grid.MasterTableView.PageSize = pageSize;
			grid.FilterMenu.Items.Add(new RadMenuItem("In (Use:AAA,BBB,CCC)") { Value = "In", PostBack = false });

			#region DataKeys
			grid.MasterTableView.DataKeyNames = grid.MasterTableView.ClientDataKeyNames = MotoBank.MetaModel.GetClientKeyNames(WSEntityType);
			#endregion

			#region GridSortExpression
			foreach (var row in p.Sorts(ReportNameCurrent))
				grid.MasterTableView.SortExpressions.Add(
					new GridSortExpression() { FieldName = row.Key, SortOrder = row.Value.Order.Convert() });
			if (grid.MasterTableView.SortExpressions.Count == 0 && DefaultSort + "" != "")
				foreach (var sort in DefaultSort.Split(','))
					grid.MasterTableView.SortExpressions.Add(
					new GridSortExpression() {
						FieldName = sort.Split('|')[0],
						SortOrder = GridSortExpression.SortOrderFromString(sort.Split('|').Last())
					});
			#endregion

			#region Delete Column
			//if (CanDelete) AddDeleteColumn();
			#endregion

			#region Auto Columns
			var autoColumns = from field in MetaColumns
												join fff in ReportFields
												on field.Name.ToLower() equals fff.Key.ToLower()
												join column in grid.Columns.Cast<GridColumn>().Select(c => c.UniqueName)
												on field.Name.ToLower() equals column.ToLower() into UniqueNames
												from un in UniqueNames.DefaultIfEmpty("")	
												where un == "" && field.ColumnType != typeof(System.Data.Linq.Binary)
												orderby fff.Value
												select field;
			foreach (var ac in autoColumns) {
				if (ac.Name.ToLower() == "loanid") AddLoanPagesColumn();
				AddDataBoundColumn(ac);
			}
			#endregion

			#region LinqDatasource
			LinqDataSource ds = (grid.DataSource ?? Parent.Child(grid.DataSourceID)) as LinqDataSource;
			if (ds == null) {
				ds = new LinqDataSource();
				Controls.Add(ds);
				grid.DataSource = ds;
				ds.ContextTypeName = typeof(MotoBank).FullName;
				ds.TableName = MotoBank.MetaModel.Tables.Single(t => t.EntityType == WSEntityType).Name;
				var sort = string.Join(",", grid.MasterTableView.SortExpressions.Cast<GridSortExpression>()
					.Select(s => s.FieldName + " " + s.SortOrder).ToArray());
				var filter = (p.Report(ReportNameCurrent).FilterLinq + "").Trim()
					.Default(MotoBank.MetaModel.GetDefaultFilter(WSEntityType));
				if ((filter + "").Trim() == "") filter = MotoBank.MetaModel.GetDefaultFilter(WSEntityType);
				if (ds.TableName.Contains("TruthInLending") && string.IsNullOrEmpty(filter)) throw new Exception(ds.TableName + " is here.");
				ds.Where = filter;
				ds.OrderBy = sort;
			} 
			#endregion


			#region Wire Events
			grid.ItemCreated += new Telerik.Web.UI.GridItemEventHandler(grid_ItemCreated);
			grid.PreRender += new EventHandler(grid_PreRender);
			ds.Selected += new EventHandler<LinqDataSourceStatusEventArgs>(ds_Selected);
			ds.Selecting += new EventHandler<LinqDataSourceSelectEventArgs>(ds_Selecting);
			#endregion
			this.TraceMe("Finish");
		}
		private void AddDeleteColumn() {
			string onClick = "event.cancelBubble=true;$find($J(this).parents('TABLE:first')[0].id).deleteSelectedItems()";
			Telerik.Web.UI.GridBoundColumn gbc = new GridBoundColumn();
			gbc.HeaderText = "<img src='/App_Themes/Office2007/Grid/Delete.gif' onclick=\"" + onClick + "\">";
			gbc.DataFormatString = "<img src='/App_Themes/Office2007/Grid/Delete.gif'>";
			gbc.UniqueName = gbc.SortExpression = "Delete";
			gbc.AllowFiltering = false;
			gbc.AllowSorting = false;
			grid.MasterTableView.Columns.Add(gbc);
		}
		private void AddLoanPagesColumn() {
			string onMouseOver = "Dimok.FindMainMenu().showLoanPagesMenu(event)";
			Telerik.Web.UI.GridBoundColumn gbc = new GridBoundColumn();
			gbc.HeaderText = "<img src='/images/FAX.gif' />";
			gbc.DataFormatString = "<img src='/images/FAX.gif' />";
			gbc.UniqueName = gbc.SortExpression = "LoanPages";
			gbc.AllowFiltering = false;
			gbc.AllowSorting = false;
			grid.MasterTableView.Columns.Add(gbc);
		}
		private void AddDataBoundColumn(MetaColumn ac) {
			if (ac.ColumnType == null && CanDelete) AddDeleteColumn();
			else {
				Telerik.Web.UI.GridBoundColumn gbc = new GridBoundColumn();
				gbc.DataField = gbc.UniqueName = gbc.SortExpression = ac.Name;
				gbc.HeaderText = ac.DisplayName.MakeHeader();
				gbc.DataFormatString = ac.DataFormatString;
				gbc.AllowFiltering = gbc.AllowSorting = true;
				grid.MasterTableView.Columns.Add(gbc);
			}
		}
		bool inException = false;
		void ds_Selecting(object sender, LinqDataSourceSelectEventArgs e) {
			var ldsv = sender as LinqDataSourceView;
			//if (ldsv.TableName.Contains("v_TruthInLending")) throw new Exception(ldsv.Where);
			if (ldsv.TableName.Contains("v_TruthInLending") && string.IsNullOrEmpty(ldsv.Where))
				ldsv.Where = MotoBank.MetaModel.GetDefaultFilter(WSEntityType);
				//throw new Exception(ldsv.TableName + ".Where is Empty.");
			if (DataSourceSelected != null) DataSourceSelected(sender, e);
			//if (e.Result == null) {
			//	e.Result = new MotoBank().GetTable(WSEntityType).Where(filter).OrderBy(sort);
			//}
		}
		void ds_Selected(object sender, LinqDataSourceStatusEventArgs e) {
			var ds = grid.DataSource as LinqDataSource;
			if (typeof(System.Web.Query.Dynamic.ParseException).IsInstanceOfType(e.Exception)) {
				e.ExceptionHandled = true;
				grid.MasterTableView.FilterExpression = "";
				p.Report(ReportNameCurrent).FilterLinq = p.Grid.Filter = "";
				p.Filters_Add(ReportNameCurrent);
				p.Save();
				ds.Where = "";
				ds.OrderBy = "";
				return;
			}
		}

		void otherFieldsMenu_PreRender(object sender, EventArgs e) {
			rcmOtherFields = otherFieldsMenu.FindControl("divOtherFields") as HtmlGenericControl;
			if (rcmOtherFields == null) throw new NotImplementedException("divOtherFields element is not found in OtherFields control.");
			rcmOtherFields.ID = TargetControlID + "_OtherFields";
			var linqDSOtherFields = Dimok.Web.UI.Find.ChildByType(otherFieldsMenu, typeof(LinqDataSource)) as LinqDataSource;
			linqDSOtherFields.Selecting += new EventHandler<LinqDataSourceSelectEventArgs>(linqDSOtherFields_Selecting);
		}
		Dictionary<string,int> ReportFields {
			get {
				var columns = (p.Report(ReportNameCurrent).Columns + "").Split('\n').Where(s => s != "").ToArray();
				return (columns.Length > 0 ? columns : DefaultFieldsSafe)
					.Select((s,i)=>new {Key=s,Value=i}).ToDictionary(a=>a.Key,a=>a.Value);
			}
		}
		string[] DefaultFieldsSafe {
			get {
				return DefaultFields + "" == "" ? MotoBank.MetaModel.GetOrderedFields<DefaultFieldAttribute>(WSEntityType).ToArray() : DefaultFields.Split(',');
			}
		}
		void linqDSOtherFields_Selecting(object sender, LinqDataSourceSelectEventArgs e) {
			var gvDetailColumns = p.Details(ReportNameCurrent,DefaultOtherFields).ToDictionary(s => s.Key);
			var cols = from col in MotoBank.MetaModel.GetTable(WSEntityType).Columns
								 join gc in grid.MasterTableView.Columns.Cast<GridColumn>() on col.Name equals gc.UniqueName into gcs
								 from gridCol in gcs.DefaultIfEmpty()
								 where gridCol == null
								 orderby col.DisplayName
								 select
								 new {
									 Label = col.DisplayName,
									 DataField = col.Name,
									 DataFormatString = col.DataFormatString,
									 Position = gvDetailColumns.Keys.Contains(col.Name) ? gvDetailColumns[col.Name].Value.ColumnPosition : 1000,
									 Title = GetFieldTitle(col.Name,WSEntityType)
								 };
			e.Result = cols.OrderBy(s => s.Position).ThenBy(s => GetInnerText(s.Label));
		}
		private static string GetInnerText(string node) {
			var m = Regex.Match(node, ">(.+)<", RegexOptions.Compiled);
			return m.Success ? m.Groups[1].Value : node;
		}

		void columnsMenu_PreRender(object sender, EventArgs e) {
			rcmColumns = Dimok.Web.UI.Find.ControlByID(columnsMenu, "rcmShowColumns") as RadContextMenu;
			rcmColumns.ID = TargetControlID + "_ColumnsMenu";
			RadMenuItem rmi = rcmColumns.FindItemByText("Columns");
			var linqDS = Dimok.Web.UI.Find.ChildByType(rmi, typeof(LinqDataSource)) as LinqDataSource;
			linqDS.Selecting += new EventHandler<LinqDataSourceSelectEventArgs>(dsColumns_Selecting);
		}

		void dsColumns_Selecting(object sender, LinqDataSourceSelectEventArgs e) {
			var cols =
				from col in MetaColumns
				join rf in ReportFields on col.Name.ToLower() equals rf.Key.ToLower() into reportFields 
				from rfs in reportFields.DefaultIfEmpty(new KeyValuePair<string,int>("",1000))
				orderby col.DisplayName
				select
				new {
					UniqueName = col.Name,
					ColumnPosition =  rfs.Value,
					Checked = rfs.Key != "" ? "checked" : "",
					Label = col.DisplayName,
					Header = col.DisplayName,
					FieldName = col.DisplayName == col.Name ? "" : " -&gt; " + col.Name,
					Title = GetFieldTitle(col.Name, WSEntityType)
				};
			e.Result = cols.OrderByDescending(s => s.Checked).ThenBy(s => s.ColumnPosition).ThenBy(s => s.Header);
		}

		//bool inPreRender;
		void grid_PreRender(object sender, EventArgs e) {
			this.TraceIn("");
			var rg = sender as RadGrid;
			var i = 0;
			//inPreRender = true;
			foreach(var pi in WSEntityType.GetProperties())
				try {
					var col = rg.MasterTableView.RenderColumns.Where(c => c.UniqueName.ToLower() == pi.Name.ToLower()).SingleOrDefault();
				if (col != null) 
					col.UniqueName = pi.Name;
				} catch (Exception exc) { throw new Exception("Property:" + pi.Name, exc); }

			rg.MasterTableView.FilterExpression = p.Grid.Filter;
			foreach (var row in p.Filters(ReportNameCurrent)) {
				var col = rg.MasterTableView.GetColumnSafe(row.Key);
				if (col == null) continue;
				if (row.Value.FilterFunction == "" || Enum.GetNames(typeof(GridKnownFunction)).Contains(row.Value.FilterFunction))
					col.CurrentFilterFunction = (GridKnownFunction)Enum.Parse(typeof(GridKnownFunction), row.Value.FilterFunction == "" ? GridKnownFunction.Contains + "" : row.Value.FilterFunction);
				col.CurrentFilterValue = row.Value.FieldValue;
			}
			try {
				rg.Rebind();
			} catch {
				foreach (var column in rg.MasterTableView.RenderColumns) {
					column.CurrentFilterFunction = GridKnownFunction.NoFilter;
					column.CurrentFilterValue = "";
				}
				p.Grid.Filter = "";
				p.Filters_Add(ReportNameCurrent);
				p.Save();
				rg.Rebind();
			}
			//inPreRender = false;

			#region Load Menus
			var contents = Find.ChildrenByType(Page.Master != null ? (Control)Page.Master : Page, typeof(ContentPlaceHolder));
			var content = contents.Count > 0? contents.Single(c=>c.ID=="cphBeforeForm"): this;
			this.TraceMe("Step:" + (++i));
			if (columnsMenu == null) {
				columnsMenu = Page.LoadControl("~/Controls/_UI/Telerik/ColumnsMenu.ascx");
				columnsMenu.PreRender += new EventHandler(columnsMenu_PreRender);
				content.Controls.Add(columnsMenu);
			}
			if (otherFieldsMenu == null) {
				otherFieldsMenu = Page.LoadControl("~/Controls/_UI/Telerik/OtherFieldsMenu.ascx");
				otherFieldsMenu.PreRender += new EventHandler(otherFieldsMenu_PreRender);
				content.Controls.Add(otherFieldsMenu);
			}
			if (filtersMenu == null) {
				filtersMenu = Page.LoadControl("~/Controls/_UI/Telerik/FiltersMenu.ascx");
				filtersMenu.PreRender += new EventHandler(filtersMenu_PreRender);
				content.Controls.Add(filtersMenu);
			}
			if (sortBysMenu == null) {
				sortBysMenu = Page.LoadControl("~/Controls/_UI/Telerik/SortBysMenu.ascx");
				sortBysMenu.PreRender += new EventHandler(sortBysMenu_PreRender);
				content.Controls.Add(sortBysMenu);
			}
			if (rowContextMenu == null) {
				rowContextMenu = Page.LoadControl("~/Controls/_UI/Telerik/RowContextMenu.ascx");
				rowContextMenu.PreRender += new EventHandler(rowContextMenu_PreRender);
				content.Controls.Add(rowContextMenu);
			}
			#endregion
			this.TraceMe("Step:" + (++i));

			this.TraceOut("");
		}

		#region Menus Renders
		void sortBysMenu_PreRender(object sender, EventArgs e) {
			rcmSortBys = sortBysMenu.Child<RadContextMenu>();
			rcmSortBys.ID = TargetControlID + "_SortBysMenu";
		}

		void filtersMenu_PreRender(object sender, EventArgs e) {
			rcmFilters = filtersMenu.Child<RadContextMenu>();
			rcmFilters.ID = TargetControlID + "_FiltersMenu";
		}
		void rowContextMenu_PreRender(object sender, EventArgs e) {
			rcmRow = rowContextMenu.Child<RadContextMenu>();
			rcmRow.ID = TargetControlID + "_RowContextMenu";
		}
		#endregion

		GridHeaderItem header = null;
		void grid_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e) {
			var rg = sender as RadGrid;

			#region Header

				//if (e.Item is GridHeaderItem) {
				//  int i = 0;
				//  string s = "";
				//  header = e.Item as GridHeaderItem;
				//  var cells = header.Cells.Cast<TableHeaderCell>().ToArray();
				//  foreach (var rc in grid.MasterTableView.RenderColumns.Where(r => r.OrderIndex >= 0 && r.Visible).o) {
				//    var cell = cells[rc.OrderIndex].Controls.OfType<LinkButton>().SingleOrDefault();
				//    if (cell == null) continue;
				//    s += cell.ToolTip = rc.HeaderText;
				//    s += ";";
				//  }
				//}
			#endregion

			#region Filter
			if (e.Item is GridFilteringItem) {
				var filterItem = e.Item as GridFilteringItem;
				foreach (RadDatePicker d in Dimok.Web.UI.Find.ChildrenByType(filterItem, typeof(RadDatePicker)))
					d.DatePopupButton.Visible = false;

				#region Re-Order
				//if (!inPreRender) {
				//  int i = rg.MasterTableView.RenderColumns.Where(s => s.OrderIndex > 0).Min(s => s.OrderIndex);
				//  GridColumn[] renderColumns = rg.MasterTableView.RenderColumns.Where(s => s.Reorderable).ToArray();
				//  string[] orderedColumns = p.GridViewReportColumns(ReportNameCurrent,DefaultFieldsSafe);
				//  foreach (string colName in orderedColumns) {
				//    var col = rg.MasterTableView.RenderColumns.Where(s => s.UniqueName.ToLower() == colName.ToLower());
				//    if (col.Count() > 0) col.ToArray()[0].OrderIndex = i++;
				//  }
				//  var cols = from col in rg.MasterTableView.RenderColumns
				//             where !orderedColumns.Select(s=>s.ToLower()).Contains(col.UniqueName.ToLower())
				//             select col;
				//  foreach (var col in cols)
				//    col.Visible = false;
				//  if (cols.Count() == rg.MasterTableView.RenderColumns.Count())
				//    cols.Where(s => s.OrderIndex > 0).OrderBy(s => s.OrderIndex).First().Visible = true;
				//}
				#endregion

				#region OnKeyPress
				//if (inPreRender)
				  foreach (var col in rg.MasterTableView.RenderColumns) {
						if (col.OrderIndex < 0) continue;
						GridBoundColumn gbCol = col as GridBoundColumn;
						if (gbCol != null && gbCol.DataType == typeof(DateTime) && gbCol.DataFormatString + "" == "") {
							gbCol.DataFormatString = "{0:MM/dd/yyyy}";
						}
				//    col.FilterListOptions = GridFilterListOptions.AllowAllFilters;
						var colName = col.UniqueName;
						var onKeyPress = String.Format("Dimok.Web.UI.RadGridBehavior.filterOnEnter(this, event, \"{0}\", \"{1}\",\"{2}\",\"{3}\");", rg.ClientID, colName, col.DataType.IsValueType ? GridKnownFunction.EqualTo : GridKnownFunction.Contains, col.DataTypeName);
						try {
							var txt = filterItem[colName].Controls[0] as TextBox;
							if (txt != null) txt.Attributes.Add("onkeydown", onKeyPress);
						} catch { }
				//    //var radInp = Dimok.Web.UI.Find.ChildByType(filterItem, typeof(RadDateInput)) as RadDateInput;
				//    //if (radInp != null) {
				//    //  radInp.OnClientDateChanged = "Bridge_DateChanged";
				//    //  radInp.Attributes.Add("onkeypress", onKeyPress);
				//    //}
					}
				#endregion
			}
			#endregion

			#region Pager
			if (e.Item is GridPagerItem) {
				RadNumericTextBox goToPageText = (RadNumericTextBox)e.Item.FindControl("GoToPageTextBox");
				goToPage = new RadNumericTextBox();
				goToPage.ID = "GoToPage";
				goToPage.Width = Unit.Pixel(40);
				goToPage.ShowSpinButtons = true;
				goToPage.Style.Add("color", "gray");
				goToPage.NumberFormat.DecimalDigits = 0;
				goToPage.CssClass = goToPageText.CssClass;
				goToPage.Style.Value = goToPageText.Style.Value;
				goToPage.Skin = goToPageText.Skin;
				goToPage.Value = 1;
				goToPage.MinValue = 1;
				//goToPage.ClientEvents.OnLoad = "function(sender,args){sender.get_element().attachEvent('onkeydown',doEnterKey)}";
				goToPage.PreRender += new EventHandler(goToPage_PreRender);
				goToPageText.Parent.Controls.AddAt(0, goToPage);

				changePageSize = (RadNumericTextBox)e.Item.FindControl("ChangePageSizeTextBox");
                changePageSize.Width = 20;

				//changePageSize.ClientEvents.OnValueChanged = "$find('"+rg.ClientID+"').onChangePageSize";
				//changePageSize.PreRender += new EventHandler(changePageSize_PreRender);
				//changePageSize.ClientEvents.OnLoad = ;
				//rg.ClientSettings.ClientEvents.OnGridCreated = "function(sender,args){debugger;$find('" + changePageSize.ClientID + "').set_maxValue(100000)}";

				((Control)e.Item.FindControl("GoToPageLabel")).Visible = false;
				((Control)e.Item.FindControl("ChangePageSizeLinkButton")).Visible = false;
				((Control)e.Item.FindControl("GoToPageLinkButton")).Visible = false;
			}
			#endregion
		}

		#region Render
		protected override void OnPreRender(EventArgs e) {
			this.TraceMe("Start");
			base.OnPreRender(e);
			grid.ClientSettings.ClientEvents.OnCommand = "OnRadGridCommandDummy";
			grid.ClientSettings.ClientEvents.OnFilterMenuShowing = "function(sender,eventArgs){if( event && event.getAttribute('cancelFilterMenu') )eventArgs.set_cancel(true);}";
			Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "OnRadGridCommandDummy",
				"function OnRadGridCommandDummy(sender, eventArgs) { eventArgs.set_cancel(true); }", true);
			this.TraceMe("End");
		}
		void goToPage_PreRender(object sender, EventArgs e) {
			var goToPageText = (RadNumericTextBox)goToPage.Parent.FindControl("GoToPageTextBox");
			goToPage.CssClass = goToPageText.CssClass;
			goToPage.Style.Value = goToPageText.Style.Value;
			goToPageText.Visible = false;
			var rg = grid;
			string onLoadScript = InitGridFilterFunctionEnum();
			onLoadScript += @"
Sys.Application.add_load(function(){
	var grid = $find('" + rg.ClientID + @"');
	// Fix submit
	var inputs = grid.get_element().all.tags('INPUT');
	for (var i = 0; i < inputs.length; i++)
		if (inputs[i].type != 'text') inputs[i].tabIndex = -1;

	$get('" + goToPage.ClientID + @"_text').attachEvent('onkeydown',doEnterKey);
	$get('" + changePageSize.ClientID + @"_text').attachEvent('onkeydown',doEnterKey);
	var tableView = $find('" + rg.ClientID + @"').get_masterTableView();
";
			foreach (GridSortExpression sort in rg.MasterTableView.SortExpressions)
				onLoadScript += InitSortScript(rg, sort);
			foreach (var filter in p.Filters(ReportNameCurrent))
				onLoadScript += InitFilterScript(rg, filter);
			onLoadScript += @"
$find('" + ClientID + @"')._decorateFilters();
";
			foreach (GridColumn column in rg.MasterTableView.RenderColumns.Where(s=>s.HeaderText!="" && s.Visible))
				onLoadScript += InitColumnsScript(column,WSEntityType);
			onLoadScript += "});";
			Page.ClientScript.RegisterStartupScript(rg.GetType(), rg.ClientID, onLoadScript, true);
		}

		protected override void Render(HtmlTextWriter writer) {
			base.Render(writer);
		}

		static string InitGridFilterFunctionEnum() {
			List<string> lst = new List<string>();
			foreach (GridKnownFunctionEx gkf in Enum.GetValues(typeof(GridKnownFunctionEx)))
				lst.Add(@"
Sys.Application.add_init(function(){
	Telerik.Web.UI.GridFilterFunction.prototype." + gkf + " = " + (int)gkf + @";
	Telerik.Web.UI.GridFilterFunction." + gkf + " = " + (int)gkf + @";
});
");
			return string.Join("", lst.ToArray());

		}
		static string InitFilterScript(RadGrid Grid, KeyValuePair<string,UserSettings.Page.Grid.Report.Filter> Exp) {
			var column = Grid.MasterTableView.GetColumnSafe(Exp.Key);
			var headerText = column == null ? Exp.Key : column.HeaderText.Replace("'", "\"");
			return @"
	var filterExps = $find('" + Grid.ClientID + @"').get_masterTableView().get_filterExpressions();
	var filterExp = new Telerik.Web.UI.GridFilterExpression();
	filterExp.set_columnUniqueName('" + Exp.Key + @"');
	filterExp.set_fieldName('" + Exp.Value.FieldName + @"');
	filterExp.set_fieldValue('" + Exp.Value.FieldValue.Replace("'", "\\'") + @"');
	filterExp.set_dataTypeName('" + Exp.Value.DataTypeName + @"');
	filterExp.set_filterFunction('" + Exp.Value.FilterFunction + @"');
	filterExp.HeaderText = '"+headerText+@"'
	filterExps.add(filterExp);
	filterExp = null;
	filterExps = null;
	var filterFunction = "
+(Enum.IsDefined(typeof(GridKnownFunctionEx), Exp.Value.FilterFunction)?
	(int)Enum.Parse(typeof(GridKnownFunctionEx), Exp.Value.FilterFunction):
	(int)Enum.Parse(typeof(GridKnownFunction), Exp.Value.FilterFunction)
	)+@";
	var tableView = $find('" + Grid.ClientID + @"').get_masterTableView();
	var column = tableView.getColumnByUniqueName('" + Exp.Key + @"');
	if( column ){"+(column==null?"":@"
		column.HeaderText = '"+column.HeaderText.Replace("'","\"")+@"';
")+@"
		column._data.CurrentFilterFunction = filterFunction;
		column._data.CurrentFilterFunctionName = '" + Exp.Value.FilterFunction + @"';
	}
";
		}
		static string InitColumnsScript(GridColumn column,Type EntityType) {
			return @"
	var column = tableView.getColumnByUniqueName('" + column.UniqueName + @"');
	column._data.DataField = '" + column.UniqueName + @"';
	column.HeaderText = '" + column.HeaderText.Replace("'", "\"") + @"';
	(column.get_element().all.tags('A')[0]||{}).title = '" + GetFieldTitle(column.UniqueName, EntityType) +@"'
";
		}
		static string InitSortScript(RadGrid Grid, GridSortExpression Exp) {
			var column = Grid.MasterTableView.GetColumnSafe(Exp.FieldName);
			var headerText = column == null ? Exp.FieldName : column.HeaderText.Replace("'", "\"");
			return @"
	var sortExps = $find('" + Grid.ClientID + @"').get_masterTableView().get_sortExpressions();
	var sortExp = new Telerik.Web.UI.GridSortExpression();
	sortExp.set_fieldName('" + Exp.FieldName + @"');
	sortExp.set_sortOrder(" + (int)Exp.SortOrder + @");
	sortExp.HeaderText = '" + headerText + @"'
	sortExps.add(sortExp);
	sortExp = null;
	sortExps = null;
";
		}
		#endregion

		#region Clent Extender
		protected override IEnumerable<ScriptDescriptor>GetScriptDescriptors(System.Web.UI.Control targetControl) {
			if (inException) yield break;
			ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("Dimok.Web.UI.RadGridBehavior", targetControl.ClientID);
			descriptor.AddProperty("columnsMenuID", rcmColumns.ClientID);
			descriptor.AddProperty("otherFieldsMenuID", rcmOtherFields.ClientID);
			descriptor.AddProperty("filtersMenuID", rcmFilters.ClientID);
			descriptor.AddProperty("sortBysMenuID", rcmSortBys.ClientID);
			if (OnRowContextMenuShowing + "" != "") descriptor.AddEvent("rowContextMenuShowing", OnRowContextMenuShowing);
			if (OnRowContextMenuShowed + "" != "") descriptor.AddEvent("rowContextMenuShowed", OnRowContextMenuShowed);
			descriptor.AddProperty("rowContextMenuID", RowContextMenuID + "" != "" ? RowContextMenuID : rcmRow.ClientID);
			if (DefaultFilterTemp + "" != "") descriptor.AddProperty("filterTempDefault", DefaultFilterTemp);
			descriptor.AddProperty("wsEntityType", WSEntityType.FullName);
			if (WSMethodName + "" != "") descriptor.AddProperty("wsMethodName", WSMethodName);
			if (WSMethodName_Delete + "" != "") descriptor.AddProperty("wsMethodName_Delete", WSMethodName_Delete);
			descriptor.AddProperty("pageSizeBoxID", changePageSize.ClientID);
			descriptor.AddProperty("goToPageBoxID", goToPage.ClientID);
			descriptor.AddProperty("pageCountLabelID", grid.MasterTableView.ClientID + "PCN");
			descriptor.AddProperty("pageType", this.Page.GetType().Name);
			descriptor.AddProperty("id", this.ClientID);
			descriptor.AddComponentProperty("grid", grid.ClientID);
			if (ProfileID + "" == "") throw new MissingMemberException("ProfileID attribute is missing for ["+this.ClientID+"].");
			descriptor.AddProperty("profileID", ProfileID);
			descriptor.AddProperty("detailViewDimensions", new Dimok.Web.UI.DSs.Dimension(p.Report(ReportNameCurrent).DetailViewXYWH));
			descriptor.AddProperty("clientDataKeyNames", grid.MasterTableView.ClientDataKeyNames);
			descriptor.AddScriptProperty("activeRowKey", (p.Grid.ActiveRowKey + "").Default("null", "{}").Default("{}"));
			if (DocksID + "" != "") descriptor.AddProperty("docksID", DocksID);
			var mt = MotoBank.MetaModel.GetTable(WSEntityType);
			var mcs = (from mc in mt.Columns.Cast<System.Web.DynamicData.MetaColumn>()
								 select new { EditAttr = mc.Attributes.OfType<EditColumnTemplateAttribute>().SingleOrDefault(), ColName = mc.Name }
								).Where(mc => mc.EditAttr != null).
									ToDictionary(mc => mc.ColName,
																mc => new {
																	mc.EditAttr.ElementCss,
																	mc.EditAttr.EditEvent,
																	mc.EditAttr.Template,
																	LookUpFieldName = mc.EditAttr.LookUpFieldName.Default(mc.ColName),
																	mc.EditAttr.LookUpTextField,
																	mc.EditAttr.LookUpValueField,
																	mc.EditAttr.LookUpEntity,
																	mc.EditAttr.IsEdit,
																	mc.EditAttr.IsEditAll,
																	mc.EditAttr.IsAdd
																}
									);
			descriptor.AddProperty("metaFields", mcs);
			descriptor.AddProperty("detailKeyNames", MotoBank.MetaModel.GetDetailKeyNames(WSEntityType));
			descriptor.AddProperty("canUpdate", MotoBank.MetaModel.CanUpdate(WSEntityType));
			descriptor.AddProperty("canDelete", MotoBank.MetaModel.CanDelete(WSEntityType));
			descriptor.AddProperty("canInsert", MotoBank.MetaModel.CanInsert(WSEntityType));
			descriptor.AddProperty("canHaveDocs", MotoBank.MetaModel.GetMetaColumn(WSEntityType.FullName, "GUID_Documents", false) != null);
			yield return descriptor;
		}
		protected override IEnumerable<ScriptReference>GetScriptReferences() {
			if (inException) yield break;
			yield return new ScriptReference("Dimok.Web.UI.JS.JQuery.jeditable.js", "Dimok.Web.UI");
			yield return new ScriptReference("/JS/UI/jEditable.inputTypes.js");
			yield return new ScriptReference("/JS/UI/Telerik/RadGridBehavior.js");
			yield return new ScriptReference("/JS/UI/Telerik/TelerikOverride.js");
		}
		#endregion
		#region Helpers
		private static string GetFieldTitle(string columnName, Type EntityType) {
			return MotoBank.MetaModel.GetTable(EntityType)
				.Columns.Where(c => c.Name == columnName)
				.Select(c => c.Attributes.OfType<HtmlTitleAttribute>().Where(a => a.Title + "" != "").Select(a => a.Title).SingleOrDefault())
				.SingleOrDefault() ?? columnName.MakeHeader();
		}
		#endregion
	}
}